package com.zc.framework.shiro.security;

import com.zc.app.sys.service.UserService;
import com.zc.framework.shiro.RealmEventListener;
import com.zc.framework.shiro.RealmEventManager;
import com.zc.framework.shiro.bean.Principal;
import com.zc.framework.shiro.cas.CasMatcher;
import com.zc.framework.spring.SpringContextHolder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;

import javax.annotation.PostConstruct;
import java.util.Iterator;

/**
 * Created by zc on 2016/8/30.
 */
public class SystemAuthorizingRealm2 extends AuthorizingRealm implements RealmEventListener {

    private static final Logger log = LogManager.getLogger(SystemAuthorizingRealm2.class);
    private CasMatcher casMatcher;
    private UserService userService;

    public CasMatcher getCasMatcher() {
        return casMatcher;
    }

    public void setCasMatcher(CasMatcher casMatcher) {
        this.casMatcher = casMatcher;
    }

    public SystemAuthorizingRealm2() {
    }

    protected void onInit() {
        super.onInit();
        RealmEventManager.getInstance().registReamlInstance(this);
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        Principal principal = (Principal)this.getAvailablePrincipal(principals);
//        User user = this.getUserService().findByUsername(principal.getLoginName());

//        if(user == null){
//            return null;
//        } else {
//            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//            List list = this.getUserService().getAuthorizedMenusByUserId(user.getId());
//            Iterator roles = list.iterator();
//
//            Menu menu;
//            do {
//                if (!roles.hasNext()) {
//                    List roleList = user.getRoleList();
//                    Iterator roleIterator = roleList.iterator();
//
//                    while (roleIterator.hasNext()) {
//                        Role roleItem = (Role) roleIterator.next();
//                        info.addRole(roleItem.getName());
//                    }
//
//                    if (user != null && user.getId() != null && StringUtils.isNotBlank(user.getId())) {
//                        this.getUserService().updateUserLoginInfo(user.getLoginName());
//                    }
//                    return info;
//                }
//                menu = (Menu) roles.next();
//            } while (!StringUtils.isNotBlank(menu.getPermission()));
//
//            String[] item = StringUtils.split(menu.getPermission(), ",");
//            int permissionLength = item.length;
//
//            for (int index = 0; index < permissionLength; ++index) {
//                String permission = item[index];
//                info.addStringPermission(permission);
//            }

//            return  info;
//        }
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
//        UsernamePasswordToken2 token = (UsernamePasswordToken2)authcToken;
//        User user = this.getUserService().findByUsername(token.getUsername());
//        if(user != null) {
//            log.info("userName", new Object[]{token.getUsername()});
//            byte[] salt = Encodes.decodeHex(user.getLoginPassword().substring(0, 16));
//            return new SimpleAuthenticationInfo(new Principal(user), user.getLoginPassword().substring(16), ByteSource.Util.bytes(salt), this.getName());
//        } else {
//            throw new AuthenticationException("用户名或者密码错误");
//        }
        return null;
    }

    @PostConstruct
    public void initCredentialsMatcher() {
        if(this.casMatcher == null) {
            log.error("CredentialsMatcher not configed, please set instance of CasMatcher", (Throwable)null);
        }

        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(this.casMatcher.getAlgorithm());
        matcher.setHashIterations(this.casMatcher.getHashIterations());
        this.setCredentialsMatcher(matcher);
    }

    @Override
    public void clearCachedAuthorizationInfo(String principal) {
        SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, this.getName());
        this.clearCachedAuthorizationInfo(principals);
    }

    @Override
    public void clearAllCachedAuthorizationInfo() {
        Cache cache = this.getAuthorizationCache();
        if(cache != null) {
            Iterator item = cache.keys().iterator();
            while(item.hasNext()) {
                Object key = item.next();
                cache.remove(key);
            }
        }
    }

    public UserService getUserService() {
        if(this.userService==null){
//            this.userService = SpringContextHolder.getBean(UserService.class);
        }
        return userService;
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}
